<template>
  <div>
    <div>
      <el-row>
        <el-button type="primary" size="mini" @click="append(null)">添加菜单</el-button>
        <el-button type="primary" size="mini" @click="refresh">刷新</el-button>
      </el-row>
    </div>
    <div class="custom-tree-container">
      <div class="block">
        <el-tree
          v-loading="treeLoading"
          element-loading-text="加载中"
          :data="data"
          :show-checkbox="false"
          ref="tree"
          node-key="id"
          :default-expand-all="false"
          :expand-on-click-node="false">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{node.data.menuTitle }}</span>
        <span>
          <el-button
            type="text"
            size="mini"
            @click="() => editMenu(data)">
            编辑
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => append(data)">
            添加子菜单
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => remove(node, data)">
            删除
          </el-button>
        </span>
      </span>
        </el-tree>
      </div>
    </div>
    <div>
      <el-dialog title="菜单信息" :close-on-click-modal=false :close-on-press-escape=false :visible.sync="dialogFormVisible"
                 @close="clearDialog" v-loading="formLoading" element-loading-text="加载中">
        <el-form :model="menuForm" size="mini">
          <el-form-item label="上级菜单ID" :label-width="formLabelWidth">
            <el-input v-model="menuForm.parentId" :readonly="true"></el-input>
          </el-form-item>
          <el-form-item label="名字" :label-width="formLabelWidth">
            <el-input v-model="menuForm.menuName"></el-input>
          </el-form-item>
          <el-form-item label="标题" :label-width="formLabelWidth">
            <el-input v-model="menuForm.menuTitle"></el-input>
          </el-form-item>
          <el-form-item label="叶子节点" :label-width="formLabelWidth">
            <el-select v-model="menuForm.isLeaf">
              <el-option label="是" value="1"></el-option>
              <el-option label="否" value="0"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="层级" :label-width="formLabelWidth">
            <el-select v-model="menuForm.menuLevel">
              <el-option label="1" value="1"></el-option>
              <el-option label="2" value="2"></el-option>
              <el-option label="3" value="3"></el-option>
              <el-option label="4" value="4"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="URL" :label-width="formLabelWidth">
            <el-input v-model="menuForm.path"></el-input>
          </el-form-item>
          <el-form-item label="视图路径" :label-width="formLabelWidth">
            <el-input v-model="menuForm.viewPath"></el-input>
          </el-form-item>
          <el-form-item label="redirect" :label-width="formLabelWidth">
            <el-input v-model="menuForm.redirect"></el-input>
          </el-form-item>
          <el-form-item label="图标" :label-width="formLabelWidth">
            <el-input v-model="menuForm.icon"></el-input>
          </el-form-item>
          <el-form-item :label-width="formLabelWidth">
            <el-checkbox v-model="menuForm.alwaysShow" true-label="1" false-label="0">总是显示</el-checkbox>
            <el-checkbox v-model="menuForm.noCache" true-label="1" false-label="0">不缓存</el-checkbox>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取 消</el-button>
          <el-button type="primary" @click="saveMenu">提交</el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
  import { queryMenuNodeTree, queryMenuInfo, saveMenuInfo, deleteMenu } from '@/api/menu'
  import { dynamicMessage, messageError, notifyError } from '@/utils/message'

  export default {
    name: 'Menu',
    data() {
      return {
        data: [],
        dialogFormVisible: false,
        menuInitType: 'update',
        editId: null,
        menuForm: {},
        formLabelWidth: '100px',
        treeLoading: false,
        formLoading: true
      }
    },
    mounted: function() {
      this.fetchMenuData()
    },
    methods: {
      editMenu(data) {
        this.menuInitType = 'update'
        this.editId = data.id
        this.fetchSingleMenu(data.id)
        this.dialogFormVisible = true
      },
      append(data) {
        this.menuInitType = 'add'
        this.editId = data ? data.id : null
        this.menuForm.parentId = data ? data.id : 0
        this.menuForm.menuLevel = data ? data.menuLevel + 1 : 1
        this.dialogFormVisible = true
      },
      remove(node, data) {
        this.$confirm('确认删除吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.deleteMenu(data)
          const parent = node.parent
          const children = parent.data.children || parent.data
          const index = children.findIndex(d => d.id === data.id)
          children.splice(index, 1)
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
      },
      clearDialog() {
        this.menuForm = {}
        this.editId = null
      },
      saveMenu(data) {
        this.submitMenuInfo(data)
      },
      appendChild(data) {
        const child = {
          id: data.id,
          menuName: data.menuName,
          menuTitle: data.menuTitle,
          parentId: data.parentId
        }
        if (this.editId) {
          let currentNode = this.$refs.tree.getNode(this.editId)
          let currentData = currentNode.data
          if (!currentData.children) {
            this.$set(nodeData, 'children', [])
          }
          currentData.children.push(child)
        } else {
          this.data.push(child)
        }
      },
      updateNodeInfo(data) {
        if (this.editId) {
          let currentNode = this.$refs.tree.getNode(this.editId)
          let currentData = currentNode.data
          currentData.menuName = data.menuName
          currentData.menuTitle = data.menuTitle
        }
      },
      refresh() {
        this.fetchMenuData()
      },
      loading(loading) {
        loading = true
      },
      done(loading) {
        loading = false
      },
      async submitMenuInfo() {
        const { code, message, data } = await saveMenuInfo(this.menuInitType, this.menuForm)
        try {
          if (this.menuInitType == 'add') {
            this.appendChild(data)
          } else {
            this.updateNodeInfo(data)
          }
          dynamicMessage(code, message)
          this.dialogFormVisible = false
        } catch (e) {
          messageError(null)
          notifyError(e.message)
        }
      },
      async fetchMenuData() {
        this.loading(this.treeLoading)
        const paramObj = { menuLevel: 1 }
        const { data } = await queryMenuNodeTree(paramObj)
        this.data = data
        this.done(this.treeLoading)
      },
      async fetchSingleMenu(id) {
        this.loading(this.formLoading)
        const { data } = await queryMenuInfo(id)
        this.menuForm = data
        this.done(this.formLoading)
      },
      async deleteMenu(data) {
        await deleteMenu(data.id)
      }
    }
  }
</script>

<style scoped>
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
</style>
